-- Lua Battle System - 动态配置管理系统
-- 提供配置热更新、动态调整和配置验证功能

local Logger = require("utils.logger")
local TableUtils = require("utils.table_utils")
local ConfigValidator = require("utils.config_validator")

local DynamicConfigManager = {
    -- 配置管理器配置
    config = {
        -- 配置文件监控
        file_monitoring = {
            enabled = true,
            check_interval = 5, -- 秒
            auto_reload = true,
            backup_on_change = true
        },

        -- 配置验证
        validation = {
            strict_mode = true, -- 严格模式，任何验证失败都会阻止更新
            validate_on_load = true,
            validate_on_change = true,
            custom_validators = {}
        },

        -- 配置历史
        history = {
            enabled = true,
            max_history_size = 50, -- 最大历史记录数
            save_on_change = true,
            auto_cleanup = true
        },

        -- 配置缓存
        cache = {
            enabled = true,
            ttl = 300, -- 缓存生存时间（秒）
            max_cache_size = 100
        },

        -- 配置回滚
        rollback = {
            enabled = true,
            auto_rollback_on_error = true,
            rollback_timeout = 30, -- 自动回滚超时时间（秒）
            max_rollback_attempts = 3
        }
    },

    -- 当前状态
    state = {
        is_initialized = false,
        config_registry = {}, -- 配置注册表
        config_cache = {}, -- 配置缓存
        config_history = {}, -- 配置历史
        change_listeners = {}, -- 变更监听器
        validation_rules = {}, -- 验证规则
        file_watchers = {}, -- 文件监控器
        last_update_time = 0,
        update_count = 0
    },

    -- 配置模块映射
    config_modules = {
        system = "src/config/system_config.lua",
        battle = "src/config/battle_config.lua",
        ai = "src/config/ai_config.lua",
        performance = "src/config/performance_config.lua"
    }
}

-- 初始化动态配置管理器
function DynamicConfigManager:init(config)
    Logger.info("初始化动态配置管理系统")

    -- 合并配置
    if config then
        TableUtils.merge(self.config, config)
    end

    -- 初始化配置注册表
    self:init_config_registry()

    -- 初始化验证规则
    self:init_validation_rules()

    -- 加载初始配置
    self:load_initial_configs()

    -- 启动文件监控
    if self.config.file_monitoring.enabled then
        self:start_file_monitoring()
    end

    self.state.is_initialized = true
    self.state.last_update_time = os.time()

    Logger.info("动态配置管理系统初始化完成", {
        registered_configs = #self:get_registered_config_names(),
        file_monitoring_enabled = self.config.file_monitoring.enabled
    })
end

-- 初始化配置注册表
function DynamicConfigManager:init_config_registry()
    for config_name, file_path in pairs(self.config_modules) do
        self:register_config(config_name, file_path)
    end
end

-- 注册配置
function DynamicConfigManager:register_config(name, file_path, options)
    if not name or not file_path then
        Logger.error("配置注册失败：缺少名称或文件路径")
        return false
    end

    options = options or {}

    local config_info = {
        name = name,
        file_path = file_path,
        loaded = false,
        last_modified = 0,
        load_count = 0,
        validation_schema = options.validation_schema,
        hot_reload_enabled = options.hot_reload_enabled ~= false, -- 默认启用
        dependencies = options.dependencies or {},
        priority = options.priority or 0
    }

    self.state.config_registry[name] = config_info

    Logger.debug("已注册配置", {name = name, file_path = file_path})

    return true
end

-- 初始化验证规则
function DynamicConfigManager:init_validation_rules()
    -- 系统配置验证规则
    self.state.validation_rules.system = {
        system = {
            version = {type = "string", required = true},
            name = {type = "string", required = true}
        },
        logging = {
            level = {type = "string", enum = {"debug", "info", "warn", "error"}},
            enable_file_logging = {type = "boolean"},
            max_log_size = {type = "number", min = 1024}
        },
        performance = {
            max_fps = {type = "number", min = 1, max = 120},
            update_interval = {type = "number", min = 1}
        }
    }

    -- 战斗配置验证规则
    self.state.validation_rules.battle = {
        battle_rules = {
            max_turns = {type = "number", min = 1, max = 1000},
            turn_time_limit = {type = "number", min = 1},
            max_team_size = {type = "number", min = 1, max = 10}
        },
        damage_calculation = {
            critical_multiplier = {type = "number", min = 1.0, max = 5.0},
            critical_chance = {type = "number", min = 0.0, max = 1.0},
            miss_chance = {type = "number", min = 0.0, max = 1.0}
        },
        ai = {
            decision_time_limit = {type = "number", min = 0.1, max = 10.0},
            difficulty_levels = {
                easy = {type = "number", min = 0.0, max = 1.0},
                normal = {type = "number", min = 0.0, max = 1.0},
                hard = {type = "number", min = 0.0, max = 1.0},
                expert = {type = "number", min = 0.0, max = 1.0}
            }
        }
    }

    -- AI配置验证规则（用于AI调优系统）
    self.state.validation_rules.ai = {
        parameter_tuning = {
            learning_rate = {type = "number", min = 0.001, max = 1.0},
            tuning_interval = {type = "number", min = 1, max = 100},
            tuning_threshold = {type = "number", min = 0.01, max = 1.0}
        },
        strategy_weights = {
            damage_output = {type = "number", min = 0.0, max = 1.0},
            team_survival = {type = "number", min = 0.0, max = 1.0},
            resource_efficiency = {type = "number", min = 0.0, max = 1.0},
            status_effects = {type = "number", min = 0.0, max = 1.0}
        }
    }

    -- 性能配置验证规则
    self.state.validation_rules.performance = {
        monitoring = {
            interval = {type = "number", min = 1, max = 60},
            enable_profiling = {type = "boolean"}
        },
        thresholds = {
            response_time_warning = {type = "number", min = 10},
            response_time_critical = {type = "number", min = 10},
            memory_warning = {type = "number", min = 50, max = 100},
            memory_critical = {type = "number", min = 50, max = 100}
        }
    }
end

-- 加载初始配置
function DynamicConfigManager:load_initial_configs()
    for config_name, config_info in pairs(self.state.config_registry) do
        self:load_config(config_name)
    end
end

-- 加载配置文件
function DynamicConfigManager:load_config(config_name, force_reload)
    local config_info = self.state.config_registry[config_name]
    if not config_info then
        Logger.error("未找到配置: " .. config_name)
        return nil
    end

    -- 检查是否需要重新加载
    if not force_reload and config_info.loaded then
        -- 检查文件修改时间
        local current_modified = self:get_file_modified_time(config_info.file_path)
        if current_modified <= config_info.last_modified then
            return self.state.config_cache[config_name]
        end
    end

    Logger.info("加载配置文件", {name = config_name, file = config_info.file_path})

    -- 备份当前配置
    if self.config.file_monitoring.backup_on_change and config_info.loaded then
        self:backup_config(config_name)
    end

    -- 加载配置文件
    local success, config_data = pcall(dofile, config_info.file_path)
    if not success then
        Logger.error("配置文件加载失败", {
            name = config_name,
            file = config_info.file_path,
            error = config_data
        })

        if self.config.rollback.auto_rollback_on_error and config_info.loaded then
            self:rollback_config(config_name)
        end

        return nil
    end

    -- 验证配置
    if self.config.validation.validate_on_load then
        local valid, errors = self:validate_config(config_name, config_data)
        if not valid then
            Logger.error("配置验证失败", {
                name = config_name,
                errors = errors
            })
            return nil
        end
    end

    -- 更新配置信息
    config_info.loaded = true
    config_info.last_modified = self:get_file_modified_time(config_info.file_path)
    config_info.load_count = config_info.load_count + 1

    -- 缓存配置
    self.state.config_cache[config_name] = config_data

    -- 记录历史
    if self.config.history.save_on_change then
        self:save_config_history(config_name, config_data)
    end

    -- 通知监听器
    self:notify_config_listeners(config_name, config_data)

    -- 更新统计
    self.state.last_update_time = os.time()
    self.state.update_count = self.state.update_count + 1

    Logger.info("配置加载成功", {name = config_name})

    return config_data
end

-- 获取文件修改时间
function DynamicConfigManager:get_file_modified_time(file_path)
    -- 简化实现，实际中应使用系统API
    return os.time()
end

-- 验证配置
function DynamicConfigManager:validate_config(config_name, config_data)
    local validation_rules = self.state.validation_rules[config_name]
    if not validation_rules then
        return true, {} -- 没有验证规则则认为有效
    end

    local errors = {}
    local validator = ConfigValidator

    -- 递归验证配置
    local function validate_section(section_name, section_rules, section_data)
        for key, rule in pairs(section_rules) do
            local value = section_data and section_data[key]

            if rule.required and value == nil then
                table.insert(errors, string.format("%s.%s 是必需的", section_name, key))
                -- continue to next iteration
                goto continue_validation
            end

            if value ~= nil then
                -- 类型验证
                if rule.type and type(value) ~= rule.type then
                    table.insert(errors, string.format("%s.%s 类型错误，期望 %s，实际 %s",
                        section_name, key, rule.type, type(value)))
                end

                -- 枚举验证
                if rule.enum then
                    local found = false
                    for _, enum_value in ipairs(rule.enum) do
                        if value == enum_value then
                            found = true
                            break
                        end
                    end
                    if not found then
                        table.insert(errors, string.format("%s.%s 值无效，应为 %s 之一",
                            section_name, key, table.concat(rule.enum, ", ")))
                    end
                end

                -- 范围验证
                if rule.min and value < rule.min then
                    table.insert(errors, string.format("%s.%s 值过小，最小值为 %.2f",
                        section_name, key, rule.min))
                end

                if rule.max and value > rule.max then
                    table.insert(errors, string.format("%s.%s 值过大，最大值为 %.2f",
                        section_name, key, rule.max))
                end

                -- 递归验证嵌套对象
                if type(rule) == "table" and rule.type == nil then
                    validate_section(section_name .. "." .. key, rule, value)
                end
            end
            ::continue_validation::
        end
    end

    -- 执行验证
    validate_section(config_name, validation_rules, config_data)

    return #errors == 0, errors
end

-- 备份配置
function DynamicConfigManager:backup_config(config_name)
    local config_data = self.state.config_cache[config_name]
    if not config_data then
        return false
    end

    local backup_info = {
        timestamp = os.time(),
        config_name = config_name,
        config_data = TableUtils.deep_copy(config_data)
    }

    -- 创建备份记录
    if not self.state.config_backups then
        self.state.config_backups = {}
    end

    if not self.state.config_backups[config_name] then
        self.state.config_backups[config_name] = {}
    end

    table.insert(self.state.config_backups[config_name], backup_info)

    -- 限制备份数量
    local max_backups = 10
    while #self.state.config_backups[config_name] > max_backups do
        table.remove(self.state.config_backups[config_name], 1)
    end

    Logger.debug("配置备份完成", {name = config_name})

    return true
end

-- 回滚配置
function DynamicConfigManager:rollback_config(config_name)
    local backups = self.state.config_backups and self.state.config_backups[config_name]
    if not backups or #backups == 0 then
        Logger.warn("没有可回滚的配置备份", {name = config_name})
        return false
    end

    -- 获取最新备份
    local latest_backup = backups[#backups]
    local config_info = self.state.config_registry[config_name]

    Logger.info("回滚配置", {
        name = config_name,
        backup_time = os.date("%Y-%m-%d %H:%M:%S", latest_backup.timestamp)
    })

    -- 恢复配置
    self.state.config_cache[config_name] = latest_backup.config_data
    config_info.last_modified = latest_backup.timestamp

    -- 通知监听器
    self:notify_config_listeners(config_name, latest_backup.config_data)

    return true
end

-- 保存配置历史
function DynamicConfigManager:save_config_history(config_name, config_data)
    local history_entry = {
        timestamp = os.time(),
        config_name = config_name,
        config_data = TableUtils.deep_copy(config_data),
        change_type = "load"
    }

    table.insert(self.state.config_history, history_entry)

    -- 限制历史记录数量
    if #self.state.config_history > self.config.history.max_history_size then
        table.remove(self.state.config_history, 1)
    end

    Logger.debug("保存配置历史", {name = config_name})
end

-- 启动文件监控
function DynamicConfigManager:start_file_monitoring()
    Logger.info("启动配置文件监控")

    -- 创建文件监控器
    for config_name, config_info in pairs(self.state.config_registry) do
        if config_info.hot_reload_enabled then
            self.state.file_watchers[config_name] = {
                config_name = config_name,
                last_check = os.time(),
                check_interval = self.config.file_monitoring.check_interval
            }
        end
    end

    -- 启动监控循环
    self:monitoring_loop()
end

-- 文件监控循环
function DynamicConfigManager:monitoring_loop()
    -- 在实际实现中，这里应该使用定时器或协程
    -- 现在提供一个简化的实现

    for watcher_name, watcher in pairs(self.state.file_watchers) do
        local current_time = os.time()

        if current_time - watcher.last_check >= watcher.check_interval then
            local config_info = self.state.config_registry[watcher.config_name]
            if config_info then
                local current_modified = self:get_file_modified_time(config_info.file_path)

                if current_modified > config_info.last_modified then
                    Logger.info("检测到配置文件变更", {
                        config = watcher.config_name,
                        file = config_info.file_path
                    })

                    if self.config.file_monitoring.auto_reload then
                        self:reload_config(watcher.config_name)
                    end
                end
            end

            watcher.last_check = current_time
        end
    end
end

-- 重新加载配置
function DynamicConfigManager:reload_config(config_name)
    Logger.info("重新加载配置", {name = config_name})
    return self:load_config(config_name, true)
end

-- 获取配置
function DynamicConfigManager:get_config(config_name)
    local config_data = self.state.config_cache[config_name]

    if not config_data then
        -- 尝试加载配置
        config_data = self:load_config(config_name)
    end

    return config_data
end

-- 更新配置项
function DynamicConfigManager:update_config(config_name, key_path, value, options)
    options = options or {}

    local config_data = self:get_config(config_name)
    if not config_data then
        Logger.error("无法更新配置：配置不存在", {name = config_name})
        return false
    end

    -- 备份当前值
    local old_value = self:get_nested_value(config_data, key_path)

    -- 更新值
    local success = self:set_nested_value(config_data, key_path, value)
    if not success then
        Logger.error("配置更新失败", {name = config_name, path = key_path})
        return false
    end

    -- 验证更新后的配置
    if self.config.validation.validate_on_change then
        local valid, errors = self:validate_config(config_name, config_data)
        if not valid then
            -- 恢复原值
            self:set_nested_value(config_data, key_path, old_value)
            Logger.error("配置更新失败：验证失败", {
                name = config_name,
                path = key_path,
                errors = errors
            })
            return false
        end
    end

    -- 记录变更历史
    if self.config.history.save_on_change then
        self:save_config_history(config_name, config_data)
    end

    -- 通知监听器
    self:notify_config_listeners(config_name, config_data, {
        type = "update",
        key_path = key_path,
        old_value = old_value,
        new_value = value
    })

    -- 更新统计
    self.state.last_update_time = os.time()
    self.state.update_count = self.state.update_count + 1

    Logger.info("配置更新成功", {
        name = config_name,
        path = key_path,
        new_value = value
    })

    return true
end

-- 批量更新配置
function DynamicConfigManager:batch_update_config(config_name, updates, options)
    options = options or {}

    local config_data = self:get_config(config_name)
    if not config_data then
        Logger.error("无法批量更新配置：配置不存在", {name = config_name})
        return false
    end

    -- 备份原始配置
    local original_config = TableUtils.deep_copy(config_data)
    local applied_updates = {}

    -- 应用更新
    local has_error = false
    for key_path, value in pairs(updates) do
        local old_value = self:get_nested_value(config_data, key_path)
        local success = self:set_nested_value(config_data, key_path, value)

        if success then
            table.insert(applied_updates, {
                key_path = key_path,
                old_value = old_value,
                new_value = value
            })
        else
            has_error = true
            break
        end
    end

    -- 验证更新后的配置
    if not has_error and self.config.validation.validate_on_change then
        local valid, errors = self:validate_config(config_name, config_data)
        if not valid then
            has_error = true
        end
    end

    -- 如果有错误，回滚所有更改
    if has_error then
        self.state.config_cache[config_name] = original_config
        Logger.error("批量配置更新失败，已回滚", {
            name = config_name,
            errors = errors or "设置值失败"
        })
        return false
    end

    -- 记录变更历史
    if self.config.history.save_on_change then
        self:save_config_history(config_name, config_data)
    end

    -- 通知监听器
    self:notify_config_listeners(config_name, config_data, {
        type = "batch_update",
        updates = applied_updates
    })

    -- 更新统计
    self.state.last_update_time = os.time()
    self.state.update_count = self.state.update_count + 1

    Logger.info("批量配置更新成功", {
        name = config_name,
        update_count = #applied_updates
    })

    return true
end

-- 获取嵌套值
function DynamicConfigManager:get_nested_value(obj, key_path)
    local keys = {}
    for key in string.gmatch(key_path, "[^.]+") do
        table.insert(keys, key)
    end

    local value = obj
    for _, key in ipairs(keys) do
        if value and type(value) == "table" then
            value = value[key]
        else
            return nil
        end
    end

    return value
end

-- 设置嵌套值
function DynamicConfigManager:set_nested_value(obj, key_path, value)
    local keys = {}
    for key in string.gmatch(key_path, "[^.]+") do
        table.insert(keys, key)
    end

    if #keys == 0 then
        return false
    end

    local current = obj
    for i = 1, #keys - 1 do
        local key = keys[i]
        if type(current[key]) ~= "table" then
            current[key] = {}
        end
        current = current[key]
    end

    current[keys[#keys]] = value
    return true
end

-- 添加配置变更监听器
function DynamicConfigManager:add_change_listener(config_name, listener_id, callback)
    if not self.state.change_listeners[config_name] then
        self.state.change_listeners[config_name] = {}
    end

    self.state.change_listeners[config_name][listener_id] = callback

    Logger.debug("添加配置变更监听器", {
        config = config_name,
        listener = listener_id
    })
end

-- 移除配置变更监听器
function DynamicConfigManager:remove_change_listener(config_name, listener_id)
    if self.state.change_listeners[config_name] then
        self.state.change_listeners[config_name][listener_id] = nil
    end

    Logger.debug("移除配置变更监听器", {
        config = config_name,
        listener = listener_id
    })
end

-- 通知配置监听器
function DynamicConfigManager:notify_config_listeners(config_name, config_data, change_info)
    local listeners = self.state.change_listeners[config_name]
    if not listeners then
        return
    end

    for listener_id, callback in pairs(listeners) do
        local success, error = pcall(callback, config_name, config_data, change_info)
        if not success then
            Logger.error("配置监听器执行失败", {
                config = config_name,
                listener = listener_id,
                error = error
            })
        end
    end
end

-- 获取配置历史
function DynamicConfigManager:get_config_history(config_name, limit)
    if config_name then
        -- 获取特定配置的历史
        local history = {}
        for _, entry in ipairs(self.state.config_history) do
            if entry.config_name == config_name then
                table.insert(history, entry)
            end
        end

        if limit then
            local start_idx = math.max(1, #history - limit + 1)
            local result = {}
            for i = start_idx, #history do
                table.insert(result, history[i])
            end
            return result
        end

        return history
    else
        -- 获取所有配置的历史
        if limit then
            local start_idx = math.max(1, #self.state.config_history - limit + 1)
            local result = {}
            for i = start_idx, #self.state.config_history do
                table.insert(result, self.state.config_history[i])
            end
            return result
        end

        return self.state.config_history
    end
end

-- 获取配置统计信息
function DynamicConfigManager:get_statistics()
    local stats = {
        registered_configs = 0,
        loaded_configs = 0,
        total_loads = 0,
        total_updates = self.state.update_count,
        cache_size = 0,
        history_size = #self.state.config_history,
        active_listeners = 0,
        uptime = os.time() - (self.state.last_update_time > 0 and self.state.last_update_time or os.time())
    }

    -- 统计注册的配置
    for _, config_info in pairs(self.state.config_registry) do
        stats.registered_configs = stats.registered_configs + 1
        if config_info.loaded then
            stats.loaded_configs = stats.loaded_configs + 1
            stats.total_loads = stats.total_loads + config_info.load_count
        end
    end

    -- 统计缓存大小
    for _ in pairs(self.state.config_cache) do
        stats.cache_size = stats.cache_size + 1
    end

    -- 统计活跃监听器
    for _, listeners in pairs(self.state.change_listeners) do
        for _ in pairs(listeners) do
            stats.active_listeners = stats.active_listeners + 1
        end
    end

    return stats
end

-- 获取已注册的配置名称
function DynamicConfigManager:get_registered_config_names()
    local names = {}
    for name, _ in pairs(self.state.config_registry) do
        table.insert(names, name)
    end
    return names
end

-- 检查配置是否已加载
function DynamicConfigManager:is_config_loaded(config_name)
    local config_info = self.state.config_registry[config_name]
    return config_info and config_info.loaded or false
end

-- 强制重新加载所有配置
function DynamicConfigManager:reload_all_configs()
    Logger.info("重新加载所有配置")

    local results = {}
    for config_name, _ in pairs(self.state.config_registry) do
        results[config_name] = self:reload_config(config_name)
    end

    return results
end

-- 导出配置数据
function DynamicConfigManager:export_configs(config_names)
    local export_data = {
        timestamp = os.time(),
        configs = {}
    }

    local names_to_export = config_names or self:get_registered_config_names()

    for _, config_name in ipairs(names_to_export) do
        local config_data = self:get_config(config_name)
        if config_data then
            export_data.configs[config_name] = TableUtils.deep_copy(config_data)
        end
    end

    return export_data
end

-- 导入配置数据
function DynamicConfigManager:import_configs(export_data, options)
    options = options or {}

    if not export_data or not export_data.configs then
        Logger.error("无效的导出数据")
        return false
    end

    local results = {}
    local has_error = false

    for config_name, config_data in pairs(export_data.configs) do
        local success = false

        if options.merge then
            -- 合并模式：更新现有配置
            success = self:batch_update_config(config_name, config_data)
        else
            -- 替换模式：完全替换配置
            self.state.config_cache[config_name] = TableUtils.deep_copy(config_data)

            local config_info = self.state.config_registry[config_name]
            if config_info then
                config_info.loaded = true
                config_info.last_modified = os.time()
            end

            success = true
        end

        results[config_name] = success
        if not success then
            has_error = true
        end
    end

    if has_error then
        Logger.warn("部分配置导入失败", {results = results})
    else
        Logger.info("配置导入成功", {count = #results})
    end

    return not has_error, results
end

-- 健康检查
function DynamicConfigManager:health_check()
    local health = {
        status = "healthy",
        issues = {},
        metrics = {}
    }

    -- 检查初始化状态
    if not self.state.is_initialized then
        table.insert(health.issues, "配置管理器未初始化")
        health.status = "error"
    end

    -- 检查配置加载状态
    local unloaded_configs = {}
    for config_name, config_info in pairs(self.state.config_registry) do
        if not config_info.loaded then
            table.insert(unloaded_configs, config_name)
        end
    end

    if #unloaded_configs > 0 then
        table.insert(health.issues, "未加载的配置: " .. table.concat(unloaded_configs, ", "))
        health.status = "warning"
    end

    -- 收集指标
    health.metrics = self:get_statistics()

    return health
end

-- 创建动态配置管理器实例
function DynamicConfigManager:new(config)
    local instance = {
        config = TableUtils.deep_copy(self.config),
        state = TableUtils.deep_copy(self.state),
        config_modules = TableUtils.deep_copy(self.config_modules)
    }

    setmetatable(instance, {__index = self})

    if config then
        TableUtils.merge(instance.config, config)
    end

    instance:init()

    return instance
end

return DynamicConfigManager